import java.awt.*;
import java.util.*;
import javax.swing.*; 
   /**
     * Provide a graphical view of a rectangular field. This is 
     * a nested class (a class defined inside a class) which
     * defines a custom component for the user interface. This
     * component displays the field.
     * This is rather advanced GUI stuff - you can ignore this 
     * for your project if you like.
     */
    public class FieldView extends JPanel
    {
        private final int GRID_VIEW_SCALING_FACTOR = 6;
        // Colors used for empty locations.
        private static final Color EMPTY_COLOR = Color.white;

        // Color used for objects that have no defined color.
        private static final Color UNKNOWN_COLOR = Color.gray;

        private int gridWidth, gridHeight;
        private int xScale, yScale;
        Dimension size;
        private Graphics g;
        private Image fieldImage;
        private HashMap colors = new HashMap<Class, Color>();
        private SimulatorModel model;
        

        /**
         * Create a new FieldView component.
         */
        public FieldView(SimulatorModel model)
        {
            this.model=model;
            size = new Dimension(0, 0);
            xScale=GRID_VIEW_SCALING_FACTOR;
            yScale=GRID_VIEW_SCALING_FACTOR;
         }
        
        
     /**
     * Define a color to be used for a given class of animal.
     * @param animalClass The animal's Class object.
     * @param color The color to be used for the given class.
     */
    public void setColor(Class animalClass, Color color)
    {
        colors.put(animalClass, color);
    }

    /**
     * @return The color to be used for a given class of animal.
     */
    private Color getColor(Class animalClass)
    {
        Color col = (Color) colors.get(animalClass);
        if(col == null) {
            // no color defined for this class
            return UNKNOWN_COLOR;
        }
        else {
            return col;
        }
    }

        /**
         * Tell the GUI manager how big we would like to be.
         */
        public Dimension getPreferredSize()
        {
            Field field=model.getField();
            return new Dimension(field.getWidth() * xScale,
                                 field.getDepth() * yScale+1);
        }

        /**
         * Prepare for a new round of painting. Since the component
         * may be resized, compute the scaling factor again.
         */
        public void update()
        {
            Field field=model.getField();
        
            if (!size.equals(getSize())) {  // if the size has changed...
                size = getSize();
                //System.out.println("size = " + size);
                fieldImage = createImage(size.width, size.height);
                g = fieldImage.getGraphics();
                double xxScale = (double) size.width / field.getWidth();
                xScale=(int) Math.ceil(xxScale);
                if(xScale < 1) {
                    xScale = GRID_VIEW_SCALING_FACTOR;
                }
                double yyScale =(double) size.height / field.getDepth();
                yScale = (int) Math.ceil(yyScale);
                if(yScale < 1) {
                    yScale = GRID_VIEW_SCALING_FACTOR;
                }
             }
      
            for(int row = 0; row < field.getDepth(); row++) {
            for(int col = 0; col < field.getWidth(); col++) {
                Animal animal = field.getAnimalAt(row, col);
                if(animal != null) {
                    drawMark(col, row, getColor(animal.getClass()));
                }
                else {
                    drawMark(col, row, EMPTY_COLOR);
                }
            }
            }
            repaint();
        }
        /**
         * Paint on grid location on this field in a given color.
         */
        public void drawMark(int x, int y, Color color)
        {
            g.setColor(color);
            g.fillRect(x * xScale, y * yScale, xScale-1, yScale-1);
        }

        /**
         * The field view component needs to be redisplayed. Copy the
         * internal image to screen.
         */
        public void paintComponent(Graphics g)
        {
            if(fieldImage != null) {
                Dimension currentSize = getSize();
                //System.out.println("currentsize = "+currentSize);
                if(size.equals(currentSize)) {
                    g.drawImage(fieldImage, 0, 0, null);
                }
                else {
                    // Rescale the previous image.
                    g.drawImage(fieldImage, 0, 0, currentSize.width, currentSize.height, null);
                }
             }
        }
    }